package org.jeecg.modules.wlhy.hyzyb.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.wlhy.customer.dto.HyCustomerAddressRecvZybDTO;
import org.jeecg.modules.wlhy.customer.dto.HyCustomerAddressSendZybDTO;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerAddressReceive;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerAddressSend;
import org.jeecg.modules.wlhy.hyzyb.constant.ZybShippingTypeEnum;
import org.jeecg.modules.wlhy.hyzyb.constant.ZybStatusEnum;
import org.jeecg.modules.wlhy.hyzyb.dto.DeviceInfoDTO;
import org.jeecg.modules.wlhy.hyzyb.dto.DeviceTrackDTO;
import org.jeecg.modules.wlhy.hyzyb.dto.FenceInfoDTO;
import org.jeecg.modules.wlhy.hyzyb.dto.ShippingFenceDTO;
import org.jeecg.modules.wlhy.hyzyb.entity.HyZybStatus;
import org.jeecg.modules.wlhy.hyzyb.entity.ZybResult;
import org.jeecg.modules.wlhy.hyzyb.mapper.HyZybMapper;
import org.jeecg.modules.wlhy.hyzyb.service.IHyZybService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import zyb.org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import zyb.org.bouncycastle.jce.provider.BouncyCastleProvider;
import zyb.org.bouncycastle.util.encoders.Base64;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class HyZybServiceImpl extends ServiceImpl<HyZybMapper, HyZybStatus> implements IHyZybService {

    private final static String DOMAIN_URL = "https://agent.haoyunbao56.com/";

    private final static String SHIPPING_FENCE_STORE = "/shipping_fence/store";

    private final static String SHIPPING_FENCE_AUTOSTORE = "/shipping_fence/device_store";

    private final static String SHIPPING_FENCE_AUTOSTORE_503NEW = "shipping_fence/device_store_new";

    //private final static String SHIPPING_AUTO_FENCE_STORE = "/shipping_fence/device_store_more";

    private final static String SHIPPING_FENCE_DELETE = "/shipping_fence/delete";

    private final static String SHIPPING_DEVICE_DELETE = "/shipping_fence/device_delete";

    private final static String SHIPPING_FENCE_POLYGON = "/shipping_fence/device_store_polygon";

    private final static String SHIPPING_DEVICE_INFO = "/device_track/fetch_device_info";

    private final static String SHIPPING_GETTRACK_BYSHIPPING = "/device_track/get_track_by_shipping";

    private final static String SHIPPING_ACTIVE_LIST = "/device_track/active_list";

    @Value(value="${zyb.privatekey:MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgeO2ZWpSSl9fPoEAFQH/1fpqgY5v2+81J85HIhjkTd5GgCgYIKoEcz1UBgi2hRANCAASv7Gw9ekVvSGJCiDWF1iwaFzJZ6djA+3JY4xAI0D+DDJa5opFZh8xbYcQMm1T9IHlx813GQ3kS0RySQJTLXNct}")
    private String PRIVATE_KEY;

    @Value(value="${zyb.agent-id:xjjmxxkjyxgs}")
    private String AGENT_ID;

    private static final BouncyCastleProvider bc = new BouncyCastleProvider();

    //编号503新接口自动模式单线路多收发货地址
    @Override
    public Result autoSetShippingFence503New(ShippingFenceDTO shippingFenceDTO,
                                             List<HyCustomerAddressSendZybDTO> sendAddressList,
                                             List<HyCustomerAddressRecvZybDTO> receiveAddressList) {

        log.info("设置智运宝_503New请求: {} -> {} -> {}", JSONUtil.toJsonStr(shippingFenceDTO),
                JSONUtil.toJsonStr(sendAddressList),
                JSONUtil.toJsonStr(receiveAddressList));

        if (StrUtil.isEmpty(shippingFenceDTO.getDevice())) {
            return Result.error("设备号不能为空");
        }

        if (CollUtil.isEmpty(sendAddressList) || CollUtil.isEmpty(receiveAddressList)) {
            return Result.error("发货和收货地址不能为空");
        }

        List<FenceInfoDTO> fenceInfoDTOList = new ArrayList<>();
        //发货地址电子围栏只有一个
        for (HyCustomerAddressSendZybDTO sendAddress : sendAddressList) {
            if (StrUtil.isEmpty(sendAddress.getShippingFence())) {
                return Result.error("未设置发货电子围栏");
            }

            JSONObject fenceObj = JSONUtil.parseObj(sendAddress.getShippingFence());
            FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
                    .fenceType(ZybShippingTypeEnum.装货围栏.getValue())
                    .address(sendAddress.getAddress())
                    .remark(sendAddress.getOrderId())
                    //经度
                    .longitude(fenceObj.getFloat("lng"))
                    //纬度
                    .latitude(fenceObj.getFloat("lat"))
                    //地区编码
                    .divisionCode(sendAddress.getAreaCode())
                    //围栏范围，单位米
                    .triggerScope(fenceObj.getInt("radius"))
                    //自定上报位置
                    //.sdk(0)
                    .build();
            fenceInfoDTOList.add(fenceInfoDTO);
        }

        //循环多个收货地址电子围栏
        for (HyCustomerAddressRecvZybDTO recvAddress : receiveAddressList) {
            if (StrUtil.isEmpty(recvAddress.getShippingFence())) {
                return Result.error("未设置收货电子围栏");
            }

            JSONObject fenceObj = JSONUtil.parseObj(recvAddress.getShippingFence());
            FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
                    .fenceType(ZybShippingTypeEnum.卸货围栏.getValue())
                    .address(recvAddress.getAddress())
                    .remark(recvAddress.getOrderId() + "_" + recvAddress.getId())
                    //经度
                    .longitude(fenceObj.getFloat("lng"))
                    //纬度
                    .latitude(fenceObj.getFloat("lat"))
                    //地区编码
                    .divisionCode(recvAddress.getAreaCode())
                    //围栏范围，单位米
                    .triggerScope(fenceObj.getInt("radius"))
                    //超过10小时自动触发收货,这个参数有BUG，需要和智运宝技术确认
                    //.intervalTime(String.valueOf(3600 * 10))
                    .build();
            fenceInfoDTOList.add(fenceInfoDTO);
        }

        shippingFenceDTO.setFenceInfoList(fenceInfoDTOList);

        String url = DOMAIN_URL + SHIPPING_FENCE_AUTOSTORE_503NEW;
        String result = post(url, shippingFenceDTO);
        log.warn("设置智运宝_503New回执 : {} <- {}", result, JSONUtil.toJsonStr(shippingFenceDTO));
        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
        if (0 != zybResult.getCode()) {
            return Result.error(zybResult.getMessage());
        }

        return Result.OK("设置电子围栏成功");
    }

    //自动创建运单模式
    @Override
    public Result autoSetShippingFence(ShippingFenceDTO shippingFenceDTO, HyCustomerAddressSend sendAddress,
                                       List<HyCustomerAddressReceive> receiveAddressList, String orderId, String orderNum) {

//        log.info("设置智运宝: {} -> {} -> {}", JSONUtil.toJsonStr(shippingFenceDTO),
//                JSONUtil.toJsonStr(sendAddress),
//                JSONUtil.toJsonStr(receiveAddressList));

        if (StrUtil.isEmpty(shippingFenceDTO.getDevice())) {
            return Result.error("设备号不能为空");
        }

        if (ObjectUtil.isEmpty(sendAddress) || CollUtil.isEmpty(receiveAddressList)) {
            return Result.error("发货和收货地址不能为空");
        }

        List<FenceInfoDTO> fenceInfoDTOList = new ArrayList<>();
        //发货地址电子围栏只有一个
        {
            if (StrUtil.isEmpty(sendAddress.getShippingFence())) {
                return Result.error("未设置发货电子围栏");
            }

            JSONObject fenceObj = JSONUtil.parseObj(sendAddress.getShippingFence());
            FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
                    .fenceType(ZybShippingTypeEnum.装货围栏.getValue())
                    .address(sendAddress.getAddress())
                    .remark(orderId)
                    //经度
                    .longitude(fenceObj.getFloat("lng"))
                    //纬度
                    .latitude(fenceObj.getFloat("lat"))
                    //地区编码
                    .divisionCode(sendAddress.getAreaCode())
                    //围栏范围，单位米
                    .triggerScope(fenceObj.getInt("radius"))
                    //自定上报位置
                    //.sdk(0)
                    .build();
            fenceInfoDTOList.add(fenceInfoDTO);
        }

        //循环多个收货地址电子围栏
        for (HyCustomerAddressReceive recvAddress : receiveAddressList) {
            if (StrUtil.isEmpty(recvAddress.getShippingFence())) {
                return Result.error("未设置收货电子围栏");
            }

            JSONObject fenceObj = JSONUtil.parseObj(recvAddress.getShippingFence());
            FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
                    .fenceType(ZybShippingTypeEnum.卸货围栏.getValue())
                    .address(recvAddress.getAddress())
                    .remark(recvAddress.getId())
                    //经度
                    .longitude(fenceObj.getFloat("lng"))
                    //纬度
                    .latitude(fenceObj.getFloat("lat"))
                    //地区编码
                    .divisionCode(recvAddress.getAreaCode())
                    //围栏范围，单位米
                    .triggerScope(fenceObj.getInt("radius"))
                    //超过10小时自动触发收货,这个参数有BUG，需要和智运宝技术确认
                    //.intervalTime(String.valueOf(3600 * 10))
                    .build();
            fenceInfoDTOList.add(fenceInfoDTO);
        }

        shippingFenceDTO.setFenceInfoList(fenceInfoDTOList);

        String url = DOMAIN_URL + SHIPPING_FENCE_AUTOSTORE;
        String result = post(url, shippingFenceDTO);
        log.warn("智运宝自动配置围栏回执报文: {} -> {}", result, JSONUtil.toJsonStr(shippingFenceDTO));
        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
        if (0 != zybResult.getCode()) {
            return Result.error(zybResult.getMessage());
        }

        return Result.OK("设置电子围栏成功");
    }


    @Override
    public Result removeDevice(String device, String orderId) {

        HyZybStatus hyZybStatus = this.getOne(new LambdaQueryWrapper<HyZybStatus>()
                .eq(HyZybStatus::getVehicleDevice, device)
                .eq(HyZybStatus::getOrderId, orderId));
        if (null == hyZybStatus) {
            return Result.error("删除失败，无此电子围栏信息");
        }

        boolean bDelete = this.removeById(hyZybStatus.getId());
        if (!bDelete) {
            return Result.error("删除电子围栏失败");
        }

        //this.cancelAutoShippingFence(device);
        return Result.OK();
    }


    @Override
    public Result cancelAutoShippingFence(String device) {

        ShippingFenceDTO shippingFenceDTO = new ShippingFenceDTO();
        shippingFenceDTO.setDevice(device);

        String url = DOMAIN_URL + SHIPPING_DEVICE_DELETE;
        String result = post(url, shippingFenceDTO);
        log.warn("智运宝终止围栏回执报文: {}, {}", result, JSONUtil.toJsonStr(shippingFenceDTO));
        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
        if (0 != zybResult.getCode()) {
            return Result.error(zybResult.getMessage());
        }

        return Result.OK("取消自动创建电子围栏成功");
    }

//    @Override
//    public Result setShippingFencePolygon(ShippingFenceDTO shippingFenceDTO, HyCustomerAddressSend sendAddress, List<HyCustomerAddressReceive> receiveAddressList) {
//
//        log.info("设置智运宝: {} -> {} -> {}", JSONUtil.toJsonStr(shippingFenceDTO),
//                JSONUtil.toJsonStr(sendAddress),
//                JSONUtil.toJsonStr(receiveAddressList));
//        if (StrUtil.isEmpty(shippingFenceDTO.getShippingNoteNumber())) {
//            return Result.error("运单号不能为空");
//        }
//
//        if (StrUtil.isEmpty(shippingFenceDTO.getDevice())
//                || StrUtil.isEmpty(shippingFenceDTO.getVehicleNumber())) {
//            return Result.error("设备号、车牌号不能为空");
//        }
//
//        if (ObjectUtil.isEmpty(sendAddress) || CollUtil.isEmpty(receiveAddressList)) {
//            return Result.error("发货和收货地址不能为空");
//        }
//
//        //分单号，取运单后4位，其实这个参数没啥用
//        shippingFenceDTO.setSerialNumber(
//                shippingFenceDTO.getShippingNoteNumber().substring(shippingFenceDTO.getShippingNoteNumber().length() - 4)
//        );
//
//        List<FenceInfoDTO> fenceInfoDTOList = new ArrayList<>();
//        int baseFenceId = 0;
//
//        //发货地址电子围栏只有一个
//        //如果是多边形围栏，同一个围栏的BaseFenceId需要填写的数据一样作为标识
//        //[{"lat":39.905259475739975,"lng":115.99293539863395},{"lat":39.87780096191168,"lng":116.0435279649559}]
//        JSONArray sendFenceArray = JSONUtil.parseArray(sendAddress.getShippingFence());
//        for (int index = 0; index < sendFenceArray.size(); index++) {
//            JSONObject fenceObj = sendFenceArray.getJSONObject(index);
//            FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
//                    .fenceType(ZybShippingTypeEnum.装货围栏.getValue())
//                    .address(sendAddress.getAddress())
//                    .remark(sendAddress.getId())
//                    //经度
//                    .longitude(new Float(fenceObj.getFloat("lng")))
//                    //纬度
//                    .latitude(new Float(fenceObj.getFloat("lat")))
//                    //地区编码
//                    .divisionCode(sendAddress.getAreaCode())
//                    //开启多边形区域
//                    .polygonType("1")
//                    .baseFenceId(baseFenceId)
//                    //出围栏触发
//                    .driverType(2)
//                    //2000米围栏范围
//                    .triggerScope(2000)
//                    //自定上报位置
//                    //.sdk(0)
//                    .build();
//            fenceInfoDTOList.add(fenceInfoDTO);
//        }
//
//        //循环多个收货地址电子围栏
//        for (HyCustomerAddressReceive recvAddress : receiveAddressList) {
//            //如果是多边形围栏，同一个围栏的BaseFenceId需要填写的数据一样作为标识
//            baseFenceId = 1;
//            //[{"lat":39.905259475739975,"lng":115.99293539863395},{"lat":39.87780096191168,"lng":116.0435279649559}]
//            JSONArray recvFenceArray = JSONUtil.parseArray(recvAddress.getShippingFence());
//            for (int index = 0; index < recvFenceArray.size(); index++) {
//                JSONObject fenceObj = recvFenceArray.getJSONObject(index);
//                FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
//                        .fenceType(ZybShippingTypeEnum.卸货围栏.getValue())
//                        .address(recvAddress.getAddress())
//                        .remark(recvAddress.getId())
//                        //经度
//                        .longitude(new Float(fenceObj.getFloat("lng")))
//                        //纬度
//                        .latitude(new Float(fenceObj.getFloat("lat")))
//                        //地区编码
//                        .divisionCode(recvAddress.getAreaCode())
//                        //开启多边形区域
//                        .polygonType("1")
//                        .baseFenceId(baseFenceId)
//                        //入围栏触发
//                        .driverType(1)
//                        //1500米围栏范围
//                        .triggerScope(1500)
//                        //超过72小时自动触发收货,这个参数有BUG，需要和智运宝技术确认
//                        //.intervalTime(String.valueOf(3600 * 72))
//                        //自定上报位置
//                        //.sdk(0)
//                        .build();
//                fenceInfoDTOList.add(fenceInfoDTO);
//            }
//            baseFenceId++;
//        }
//
//        shippingFenceDTO.setFenceInfoList(fenceInfoDTOList);
//
//        String url = DOMAIN_URL + SHIPPING_FENCE_POLYGON;
//        String result = post(url, shippingFenceDTO);
//        log.warn("智运宝开启围栏回执报文: {} -> {}", result, JSONUtil.toJsonStr(shippingFenceDTO));
//        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
//        if (0 != zybResult.getCode()) {
//            return Result.error(zybResult.getMessage());
//        }
//
//        return Result.OK("设置电子围栏成功");
//    }



//    public Result cancelShippingFence2(String device) {
//
//        ShippingFenceDTO shippingFenceDTO = new ShippingFenceDTO();
//        shippingFenceDTO.setDevice(device);
//
//        String url = DOMAIN_URL + "/shipping_fence/device_delete_more";
//        String result = post(url, shippingFenceDTO);
//        log.warn("智运宝终止围栏回执报文: {}, {}", result, JSONUtil.toJsonStr(shippingFenceDTO));
//        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
//        if (0 != zybResult.getCode()) {
//            return Result.error(zybResult.getMessage());
//        }
//
//        return Result.OK("取消电子围栏成功");
//    }

    @Override
    public Result cancelShippingFence(String shippingNoteNumber) {

        if (StrUtil.isEmpty(shippingNoteNumber)) {
            return Result.error("运单号不能为空");
        }

        ShippingFenceDTO shippingFenceDTO = new ShippingFenceDTO();
        shippingFenceDTO.setShippingNoteNumber(shippingNoteNumber);
        shippingFenceDTO.setSerialNumber(
                shippingFenceDTO.getShippingNoteNumber().substring(shippingFenceDTO.getShippingNoteNumber().length() - 4)
        );

        String url = DOMAIN_URL + SHIPPING_FENCE_DELETE;
        String result = post(url, shippingFenceDTO);
        log.warn("智运宝终止围栏回执报文: {}, {}", result, JSONUtil.toJsonStr(shippingFenceDTO));
        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
        if (0 != zybResult.getCode()) {
            return Result.error(zybResult.getMessage());
        }

        return Result.OK("取消电子围栏成功");
    }


    @Override
    public boolean isExistInThisOrder(String device, String vehicleId, String orderId) {

        //判断该车辆设备是否已经在这个货源派过车了
        if (0 < this.count(new LambdaQueryWrapper<HyZybStatus>()
                .eq(HyZybStatus::getVehicleDevice, device)
                .eq(HyZybStatus::getOrderId, orderId)
                .eq(HyZybStatus::getVehicleId, vehicleId))) {
            log.warn("检测到智运宝车辆重复派车,{} -> {} -> {}", device, vehicleId, device);
            return true;
        }

        return false;
    }

    @Override
    public List<String> getOrderIdsByDevice(String device) {

        List<HyZybStatus> hyZybStatusList = this.list(new LambdaQueryWrapper<HyZybStatus>().eq(HyZybStatus::getVehicleDevice, device));

        List<String> orderIds = hyZybStatusList.stream().filter(item->StrUtil.isNotEmpty(item.getOrderId())).map(HyZybStatus::getOrderId).collect(Collectors.toList());
        return orderIds;
    }

    @Override
    public List<DeviceInfoDTO> getActiveList() {

        String url = DOMAIN_URL + SHIPPING_ACTIVE_LIST;
        String result = post(url, "{}");
        log.warn("获取该企业下所有设备 : {}", result);
        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
        if (0 != zybResult.getCode()) {
            return null;
        }

        List<DeviceInfoDTO> deviceInfoListDTO = JSONUtil.toList(JSONUtil.parseArray(zybResult.getBody()), DeviceInfoDTO.class);
        if (CollUtil.isEmpty(deviceInfoListDTO)) {
            return null;
        }

        return deviceInfoListDTO;
    }


    @Override
    public Result getDeviceInfo(String device) {
        return getDeviceInfo(device, "");
    }

    @Override
    public Result getDeviceInfo(String device, String vehicleNumber) {

        //车牌号和设备号不能同时为空
        if (StrUtil.isEmpty(device) && StrUtil.isEmpty(vehicleNumber)) {
            return Result.error("车牌号和设备号不能同时为空");
        }

        ShippingFenceDTO shippingFenceDTO = ShippingFenceDTO.builder()
                .device(device)
                .build();
        if (StrUtil.isNotEmpty(vehicleNumber)) {
            shippingFenceDTO.setVehicleNumber(vehicleNumber);
        }

        String url = DOMAIN_URL + SHIPPING_DEVICE_INFO;
        String result = post(url, shippingFenceDTO);
        log.warn("智运宝获取设备信息: {}, {}", result, JSONUtil.toJsonStr(shippingFenceDTO));
        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
        if (0 != zybResult.getCode()) {
            return Result.error(zybResult.getMessage());
        }

        DeviceInfoDTO deviceInfoDTO = JSONUtil.toBean(JSONUtil.toJsonStr(zybResult.getBody()), DeviceInfoDTO.class, true);
        if (ZybStatusEnum.离线.getValue().equals(deviceInfoDTO.getStatus())) {
            return Result.error(201, ZybStatusEnum.离线.getMessage());
        } else if (ZybStatusEnum.未激活.getValue().equals(deviceInfoDTO.getStatus())) {
            return Result.error(ZybStatusEnum.未激活.getMessage());
        }

        return Result.OK(ZybStatusEnum.在线.getMessage());
    }

    @Override
    public Result getShippingTrack(String shippingNoteNumber) {

        ShippingFenceDTO shippingFenceDTO = ShippingFenceDTO.builder()
                .shippingNoteNumber(shippingNoteNumber)
                .serialNumber("0000")
                .build();
        //分单号，取运单后4位
//        shippingFenceDTO.setSerialNumber(
//                shippingFenceDTO.getShippingNoteNumber().substring(shippingFenceDTO.getShippingNoteNumber().length() - 4)
//        );

        String url = DOMAIN_URL + SHIPPING_GETTRACK_BYSHIPPING;
        String result = post(url, shippingFenceDTO);
        ZybResult zybResult = JSONUtil.toBean(result, ZybResult.class);
        log.warn("智运宝获取轨迹信息: {}, {}", zybResult.getMessage(), JSONUtil.toJsonStr(shippingFenceDTO));
        //1000错误特殊处理,大部分都是没有触发收货围栏导致无法获取轨迹
        if (1000 == zybResult.getCode()) {
            return Result.error(1000, "获取轨迹失败");
        }

        if (0 != zybResult.getCode()) {
            return Result.error(zybResult.getMessage());
        }

        List<DeviceTrackDTO> deviceTrackDTOList = JSONUtil.parseArray(JSONUtil.toJsonStr(zybResult.getBody())).toList(DeviceTrackDTO.class);

        return Result.OK(deviceTrackDTOList);
    }

    //智运宝发送请求
    private String post(String url, Object request) {
        String json = JSONUtil.toJsonStr(request);
        String resultString = StrUtil.EMPTY;
        CloseableHttpResponse response = null;
        try {
            String signedData = sign(PRIVATE_KEY, json);

            CloseableHttpClient httpClient = HttpClients.createDefault();

            HttpPost httpPost = new HttpPost(url);

            httpPost.addHeader("X-AGENT-ID", AGENT_ID);
            httpPost.addHeader("X-SIGNATURE", signedData);

            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }


    //生成签名
    private String sign(String apiSecret, String content) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, InvalidKeySpecException, InvalidKeySpecException {
        Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), bc);

        KeyFactory keyFact = KeyFactory.getInstance("EC", bc);
        PrivateKey privateKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(apiSecret)));
        signature.initSign(privateKey);

        byte[] plainText = content.getBytes(StandardCharsets.UTF_8);
        signature.update(plainText);
        return Base64.toBase64String(signature.sign());
    }


    //配置电子围栏
    private void setShippingFence() {

        ShippingFenceDTO shippingFenceDTO = new ShippingFenceDTO();
        shippingFenceDTO.setShippingNoteNumber("YD202304251731048451");
        shippingFenceDTO.setSerialNumber(
                shippingFenceDTO.getShippingNoteNumber().substring(shippingFenceDTO.getShippingNoteNumber().length() - 4)
        );
        shippingFenceDTO.setDevice("868120261066666");
        shippingFenceDTO.setDriverName("张三");
        shippingFenceDTO.setVehicleNumber("京A12345");

        FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
                .fenceType(1)
                .address("北京市海淀区中关村清华科技园1号楼")
                .longitude(new Float(123.456))
                .latitude(new Float(31.345))
                .sdk(1)
                .build();
        List<FenceInfoDTO> fenceInfoDTOList = new ArrayList<>();
        fenceInfoDTOList.add(fenceInfoDTO);

        shippingFenceDTO.setFenceInfoList(fenceInfoDTOList);

        String url = DOMAIN_URL + SHIPPING_FENCE_STORE;
        String result = post(url, shippingFenceDTO);
        //String apiSecret = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgVi80xzaFJE6dr7+/UDQ+nzI+tYxlSPH3jSmwKB/U2hagCgYIKoEcz1UBgi2hRANCAATUOQcyZXWEsF4ZQ4KiBNKdvOufCxk9W2aroK+TZbSrnCfY7zmp8weG3xg2oX56kPn5jAwYtZsD4CZx7wWs9QfQ";

        //String singature = sign(apiSecret, JSONUtil.toJsonStr(map));
        System.out.println("result is : " + result);

        return;
    }


    private void cancelShippingFence() {
        ShippingFenceDTO shippingFenceDTO = new ShippingFenceDTO();
        shippingFenceDTO.setShippingNoteNumber("YD202304251731048451");
        shippingFenceDTO.setSerialNumber(
                shippingFenceDTO.getShippingNoteNumber().substring(shippingFenceDTO.getShippingNoteNumber().length() - 4)
        );

        String url = DOMAIN_URL + SHIPPING_FENCE_DELETE;
        String result = post(url, shippingFenceDTO);

        System.out.println("result is : " + result);
    }


    //多边形多收货地址电子围栏
//    public static void setShippingFencePolygon() {
//        ShippingFenceDTO shippingFenceDTO = new ShippingFenceDTO();
//        shippingFenceDTO.setShippingNoteNumber("YD202304251731048451");
//        shippingFenceDTO.setSerialNumber(
//                shippingFenceDTO.getShippingNoteNumber().substring(shippingFenceDTO.getShippingNoteNumber().length() - 4)
//        );
//        shippingFenceDTO.setDevice("868120261066666");
//        shippingFenceDTO.setDriverName("张三");
//        shippingFenceDTO.setVehicleNumber("京A12345");
//
//        FenceInfoDTO fenceInfoDTO = FenceInfoDTO.builder()
//                .fenceType(1)
//                .address("北京市海淀区中关村清华科技园1号楼")
//                .longitude(new Float(123.456))
//                .latitude(new Float(31.345))
//                .sdk(1)
//                .build();
//        List<FenceInfoDTO> fenceInfoDTOList = new ArrayList<>();
//        fenceInfoDTOList.add(fenceInfoDTO);
//
//        shippingFenceDTO.setFenceInfoList(fenceInfoDTOList);
//
//        String url = DOMAIN_URL + SHIPPING_FENCE_POLYGON;
//        String result = signTest(url,shippingFenceDTO);
//        //String apiSecret = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgVi80xzaFJE6dr7+/UDQ+nzI+tYxlSPH3jSmwKB/U2hagCgYIKoEcz1UBgi2hRANCAATUOQcyZXWEsF4ZQ4KiBNKdvOufCxk9W2aroK+TZbSrnCfY7zmp8weG3xg2oX56kPn5jAwYtZsD4CZx7wWs9QfQ";
//
//        //String singature = sign(apiSecret, JSONUtil.toJsonStr(map));
//        System.out.println("result is : " + result);
//    }

    public static void main(String[] args) throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {

        //配置电子围栏(业务传入运单)
        //setShippingFence();

        //终止围栏
        //cancelShippingFence();

        //配置电子围栏（多边形）
        ShippingFenceDTO shippingFenceDTO = new ShippingFenceDTO();
        shippingFenceDTO.setShippingNoteNumber("YD202304251731048451");
        shippingFenceDTO.setSerialNumber(
                shippingFenceDTO.getShippingNoteNumber().substring(shippingFenceDTO.getShippingNoteNumber().length() - 4)
        );


        return;
    }



}
